package com.example.academic_affairs_system.exception;

import com.example.academic_affairs_system.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Optional;

/**
 * 全局异常处理
 *
 * @author hjx
 * @since 2023/02/01 12:46 PM
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
  @ExceptionHandler(value = SystemException.class)
  public R systemException(SystemException exception) {
    log.error("错误异常信息 --> {}, 可能导致的原因 -> {}", exception.getMsg(), exception.getDesc());
    return R.builder()
        .code(exception.getCode())
        .msg(exception.getMsg())
        .desc(exception.getDesc())
        .build();
  }

  @ExceptionHandler(value = MethodArgumentNotValidException.class)
  public R systemValidateException(MethodArgumentNotValidException ex) {
    log.error("错误异常信息 --> {}", ex.getMessage());
    ex.printStackTrace();
    BindingResult bindingResult = ex.getBindingResult();
    return R.validate(bindingResult);
  }

  @ExceptionHandler(value = BindException.class)
  public R systemValidateException(BindException ex) {
    log.error("错误异常信息 --> {}", ex.getMessage());
    BindingResult bindingResult = ex.getBindingResult();
    return R.validate(bindingResult);
  }

  @ExceptionHandler(value = Exception.class)
  public R exception(Exception exception) {
    log.error("错误原因信息 --> {}", String.valueOf(exception.getCause()));
    log.error("异常类信息 --> {}", exception.getClass());
    log.error(
        "异常类 -> {}, 未知信息 -> {}, 原因 -> {}",
        exception.getClass(),
        exception.getMessage(),
        exception.getCause());
    return R.builder()
        .code(-999)
        .msg("发生未知异常")
        .desc(Optional.ofNullable(exception.getCause().getMessage()).orElse(exception.getMessage()))
        .build();
  }
}
